package com.streamkar.common.es;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.streamkar.entity.es.HitEntity;
import com.streamkar.entity.es.HitsEntity;
import com.streamkar.util.Jsons;
import com.streamkar.util.StringReplaceHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * @author tyfrost
 */
@Component
public class ExecuteDslComponent {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExecuteDslComponent.class);

    @Autowired
    ESRestClient esRestClient;

    public JSONObject searchData(String index, String dsl, Map<String, String> paramsMap) throws Exception {
        String endpoint = StringUtils.join("/", index, "/_search");
        String method = "POST";
        //替换DSL字段内容
        String tempDsl = StringReplaceHelper.replaceStr(dsl, paramsMap);
        LOGGER.info("EsRestClient quota info is {}...", tempDsl);
        Response searchResponse = esRestClient.performRequest(method, endpoint, tempDsl);
        HttpEntity entity = searchResponse.getEntity();
        JSONObject result = JSONObject.parseObject(EntityUtils.toString(entity));
        JSONObject buckets = result.getJSONObject("aggregations");
        if (buckets == null) {
            buckets = result.getJSONObject("hits");
        }
        LOGGER.debug("find quota info .. {}", Jsons.instance().toJson(buckets));
        return buckets;
    }

    public JSONObject searchData(String index, String dsl) throws Exception {
        String endpoint = StringUtils.join("/", index, "/_search");
        String method = "POST";
        LOGGER.info("EsRestClient quota info is {}...", dsl);
        Response searchResponse = esRestClient.performRequest(method, endpoint, dsl);
        HttpEntity entity = searchResponse.getEntity();
        JSONObject result = JSONObject.parseObject(EntityUtils.toString(entity));
        JSONObject buckets = result.getJSONObject("aggregations");
        if (buckets == null) {
            buckets = result.getJSONObject("hits");
        }
        LOGGER.debug("find quota info .. {}", new Jsons().toJson(buckets));
        return buckets;
    }

    /**
     * 执行DSL
     *
     * @param tbName 表名
     * @param dsl    待执行DSL语句
     * @return 执行结果
     */
    public JSONArray executeDsl(String tbName, String dsl) {
        JSONArray jsonArray = new JSONArray();
        try {
            JSONObject queryObject = searchData(tbName, dsl);
            HitsEntity hitsEntity = Jsons.instance().fromJson(JSON.toJSONString(queryObject), HitsEntity.class);
            if (null != hitsEntity && !CollectionUtils.isEmpty(hitsEntity.getHits())) {
                for (HitEntity temp : hitsEntity.getHits()) {
                    JSONObject jsonObject = temp.getSource();
                    // 设置ID
                    jsonObject.put("id", temp.getId());
                    jsonArray.add(jsonObject);
                }
            }
        } catch (Exception e) {
            LOGGER.error("execute search dsl catch an exception", e);
        }
        return jsonArray;
    }

    /**
     * 执行DSL
     *
     * @param tbName   表名
     * @param dsl      待执行DSL语句
     * @param paramMap 填充参数列表
     * @return 执行结果
     */
    public JSONArray executeDsl(String tbName, String dsl, Map<String, String> paramMap) {
        JSONArray jsonArray = new JSONArray();
        try {
            JSONObject queryObject = searchData(tbName, dsl, paramMap);
            HitsEntity hitsEntity = Jsons.instance().fromJson(JSON.toJSONString(queryObject), HitsEntity.class);
            if (null != hitsEntity && !CollectionUtils.isEmpty(hitsEntity.getHits())) {
                for (HitEntity temp : hitsEntity.getHits()) {
                    jsonArray.add(temp.getSource());
                }
            }
        } catch (Exception e) {
            LOGGER.error("execute search dsl catch an exception", e);
        }
        return jsonArray;
    }
}
